package com.bluesky.framework.security.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bluesky.common.Constants;
import com.bluesky.common.bo.LoginUser;
import com.bluesky.common.bo.SysRoleBO;
import com.bluesky.common.bo.SysUserBO;
import com.bluesky.common.enums.DelFlagEnum;
import com.bluesky.common.enums.GrantTypeEnum;
import com.bluesky.common.enums.StatusEnum;
import com.bluesky.common.enums.UserPlatformEnum;
import com.bluesky.common.exception.CustomException;
import com.bluesky.framework.security.service.ICustomUserDetailsService;
import com.bluesky.system.entity.SysRole;
import com.bluesky.system.entity.SysUser;
import com.bluesky.system.service.ISysMenuService;
import com.bluesky.system.service.ISysRoleService;
import com.bluesky.system.service.ISysUserService;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 自定义UserDetails
 *
 * @author Kevin
 */
@Service
@Slf4j
public class CustomUserDetailsServiceImpl implements ICustomUserDetailsService {

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private ISysMenuService sysMenuService;

    /**
     * 是否包含admin角色
     **/
    private static Boolean hasRoleAdmin(List<SysRole> sysRoleList) {
        return sysRoleList.stream().anyMatch(item -> item.getRoleCode().equals(Constants.SUPER_ADMIN_ROLE));
    }

    @Override
    public UserDetails loadUserByMobile(String mobile) throws UsernameNotFoundException {
        SysUser sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getPhone, mobile));
        if (Objects.isNull(sysUser)) {
            log.info("登录用户：{}不存在", mobile);
            throw new UsernameNotFoundException("登录用户不存在");
        }
        if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
            log.info("登录用户：{}已被删除", mobile);
            throw new CustomException("对不起，您的账号已被删除");
        }
        if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
            log.info("登录用户：{}已被停用", mobile);
            throw new CustomException("对不起，您的账号已被停用");
        }

        SysUserBO sysUserBO = BeanUtil.copyProperties(sysUser, SysUserBO.class);

        // 查询角色列表
        List<SysRole> sysRoleList = sysRoleService.listSysRoleByUserId(sysUser.getId());

        // 设置角色列表
        sysUserBO.setRoles(sysRoleList.stream().map(item -> BeanUtil.copyProperties(item, SysRoleBO.class)).collect(Collectors.toList()));

        // 查询权限标识
        Set<String> permissions = Sets.newHashSet();
        if (hasRoleAdmin(sysRoleList)) {
            permissions.add("*:*:*");
        } else {
            permissions = sysMenuService.getPermissionsByUserId(sysUser.getId());
        }

        LoginUser loginUser = new LoginUser(UserPlatformEnum.WEB.getCode(), GrantTypeEnum.MOBILE_CODE.getCode(), sysUserBO, mobile, "", permissions);
        return loginUser;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getAccount, username));
        if (Objects.isNull(sysUser)) {
            log.info("登录用户：{}不存在", username);
            throw new UsernameNotFoundException("登录用户不存在");
        }
        if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
            log.info("登录用户：{}已被删除", username);
            throw new CustomException("对不起，您的账号已被删除");
        }
        if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
            log.info("登录用户：{}已被停用", username);
            throw new CustomException("对不起，您的账号已被停用");
        }

        SysUserBO sysUserBO = BeanUtil.copyProperties(sysUser, SysUserBO.class);

        // 查询角色列表
        List<SysRole> sysRoleList = sysRoleService.listSysRoleByUserId(sysUser.getId());

        // 设置角色列表
        sysUserBO.setRoles(sysRoleList.stream().map(item -> BeanUtil.copyProperties(item, SysRoleBO.class)).collect(Collectors.toList()));

        // 查询权限标识
        Set<String> permissions = Sets.newHashSet();
        if (hasRoleAdmin(sysRoleList)) {
            permissions.add("*:*:*");
        } else {
            permissions = sysMenuService.getPermissionsByUserId(sysUser.getId());
        }

        LoginUser loginUser = new LoginUser(UserPlatformEnum.WEB.getCode(), GrantTypeEnum.USERNAME_PASSWORD.getCode(), sysUserBO, username, sysUser.getPassword(), permissions);
        return loginUser;
    }

}
